import ast
import jsonpath
from common.handle_log import Log
from common.handle_mysql import HandleMysql

logger = Log()

"""
assert_list: 
1、必须是列表形式 
2、列表中的成员，必须是字典形式 
3、字典元素必须有3个key：expr,expected,type 
4、type表示实际与期望如何去比对，有以下值可以使用：eq,gt,in 
 """


class HandleAssert:

    def assert_response_value(self, check_list, response_dict):
        """
        :param check_str:读取断言列，列表形式，里面的每一个成员是一个断言
        :param response_dict: 接口响应结果，字典类型
        :return:
        """
        # 定义比对列表
        check_res = []
        # 把字符转化成Python列表(excel读取需转化)
        # check_list = ast.literal_eval(check_str)  # 比eval 相对安全一点

        for check in check_list:
            actual = jsonpath.jsonpath(response_dict, check["expr"])
            if isinstance(actual, list):
                actual = actual[0]
            logger.info(f"提取表达式为:\"{check['expr']}\",响应结果当中提取到的值为：{actual}")
            logger.info(f"期望结果为：{check['expected']}")

            # 与实际结果做比对
            if check["type"] == "eq":
                logger.info("比对两个值是否相等")
                logger.info(f"比对结果为：{actual == check['expected']}")
                check_res.append(actual == check["expected"])
        if False in check_res:
            logger.error("部分断言失败，请检查比对结果为False的用例")
            # raise AssertionError
            return False
        else:
            logger.info("所有断言成功")
            return True

    def assert_db(self, check_db_list):
        """
        遍历列表，访问每一组db比对
        对于每一组来讲，1）调用数据库类，执行SQL语句，调哪个方法，根据type来决定，得到实际结果
                     2）与期望结果比对
        :param check_db_list: 测试数据
            示例：[{"sql":"select * form member where mobile_phone='12345678901'","expected":"1","db_type":"count"}]
        :return:
        """
        # 所有断言结果比对列表
        check_db_res = []
        # 建立连接
        db = HandleMysql()
        # 遍历check_db_list
        for check_db_dict in check_db_list:
            logger.info(f"当前要执行的SQL语句为:{check_db_dict['sql']}")
            logger.info(f"执行SQL的类型是：{check_db_dict['db_type']}")

            # 根据type来调用不同的方法执行SQL语句
            if check_db_dict['db_type'] == "count":
                db_res = db.get_count(check_db_dict["sql"])
                logger.info(f"实际结果是:{db_res},预期结果是:{check_db_dict['expected']}")
                logger.info(f"实际结果与预计结果比对结果为:{db_res == check_db_dict['expected']}")
                check_db_res.append(db_res == check_db_dict["expected"])
        if False in check_db_res:
            logger.info("部分断言失败，请检查比对结果为False用例")
            # raise AssertionError
            return  False
        else:
            logger.info("所有断言成功")
            return True


if __name__ == '__main__':
    check_db_list = [
        {"sql": "select * from member where mobile_phone='15128288928'", "expected": 1, "db_type": "count"}]
    res = HandleAssert().assert_db(check_db_list)
    # print(res)
